package com.oop.example.work.esport;

import antlr.output.MultiFarLexer;
import com.oop.example.processing.ErrorException;
import com.oop.example.processing.ParseError;
import com.oop.example.processing.TockenMap;
import com.oop.example.processing.WarnException;
import com.oop.example.xml.Block;
import com.oop.example.xml.Example;
import com.oop.example.xml.Near;
import com.oop.example.xml.ObjectFactory;
import com.oop.example.xml.Phrase;
import com.oop.example.xml.Translation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.JAXBElement;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Token;

/**
 *
 * @author -
 */
public class FiaxedExampleInserter {

    private static boolean fuckSonya = true;
    private ObjectFactory factory;
    private TockenMap tockenMap;
    private int basePos = -1;

    public FiaxedExampleInserter(ObjectFactory factory, TockenMap tockenMap, int basePos) {
        this.factory = factory;
        this.tockenMap = tockenMap;
        this.basePos = basePos;
    }

    public List<JAXBElement<Example>> getExamples(String exTxt) {
        List<JAXBElement<Example>> examples = new ArrayList<JAXBElement<Example>>();
        exTxt = exTxt.replace("<b>", "").replace("@", "").trim();
        String[] data = exTxt.split("</b>");
        String header = data[0].trim();
        String trans = data[1].trim();
        if (trans.startsWith("/")) {
            trans = trans.replaceFirst("/", "");
        }
        if (header.contains("/")) {
            tockenMap.addTocken(Esp2PortuTockenMap.SLASH_IN_FIXED_EXAMPLE_HEADER);
        }
        if (trans.contains("/")) {
            tockenMap.addTocken(Esp2PortuTockenMap.SLASH_IN_FIXED_EXAMPLE_BODY);
        }
        checkStartsWith(header);
        String[] hdrs = null;
        if (fuckSonya) {
            String[] hdrs1 = {header};
            hdrs = hdrs1;
        } else {
            hdrs = header.split(" / ");
        }
        ArrayList<String> arr = new ArrayList<String>();
        for (String s : hdrs) {
            arr.addAll(Arrays.asList(split(s)));
        }
        for (String hdr : arr) {
            trans = trans.replaceAll("</i>", "<III>");
            String[] transs = trans.split(" / ");
            if (transs.length == 1) {
                transs = split(trans);
            }
            examples.add(getExample(hdr, transs));
        }
        return examples;
    }

    /**
     * sss cccccc/dd/tttt
     *
     */
    private static String[] split(String str) {

        System.out.println("");
        String[] list = str.trim().split("/");
        if (list.length > 2) {
            if (!fuckSonya) {
                throw new ParseError(-1, "Кол-во слешей более 1");
            }
        } else if (list.length == 1) {
            return list;
        } else if (list.length == 2) {
            if (!fuckSonya) {
                throw new WarnException("Слешей без пробелов быть не должно: " + str);
            }
        }
        String first = list[0];
        String second = list[1];
        String[] split1 = first.split(" ");
        String[] split2 = second.split(" ");

        String tmp = "";
        for (int i = 0; i < split1.length - 1; i++) {
            tmp = tmp + " " + split1[i];
        }
        second = tmp + " " + second;
        for (int i = 1; i < split2.length; i++) {
            first = first + " " + split2[i];
        }
        list[0] = first.replaceAll("  ", " ").trim();
        list[1] = second.replaceAll("  ", " ").trim();

        if (fuckSonya) {
            String[] list2 = {str};
            list = list2;
        }

        return list;
    }

    public static void main(String[] args) {
        String[] some = {"aaa bbb/ccc", "ddd/eee fff", "ggg hhh/jjj kkk", "dddd"};
        //String someStr = "ddd ggg hhh/jjj kkk yyy";
        for (String someStr : some) {
            String[] sub = split(someStr);
            for (String s : sub) {
                System.out.println(s);
            }
            System.out.println("");
        }
        //for
    }

    public JAXBElement<Example> getExample(String header, String[] transs) {
        String handled = "";
        Example example = null;
        String src = "";
        int pos = -1;
        try {
            if (header.contains("/")) {
                if (!fuckSonya) {
                    throw new ParseError(-1, "Слеш в заголовке пока не обрабатывается");
                }
            }
            example = factory.createExample();
            //
            Translation localtranslation = factory.createTranslation();
            for (String trans : transs) {
                if (trans.endsWith(".")) {
                    trans = trans.substring(0, trans.length() - 1);
                }
                src = trans;
                MultiFarLexer localLexer = new MultiFarLexer(new ANTLRStringStream(trans));
                Token token = localLexer.nextToken();
                Near localNear = factory.createNear();
                Translation.Far localFar = factory.createTranslationFar();
                localtranslation.getFar().add(localFar);
                localFar.getNear().add(localNear);
                String word = "";
                boolean afterLabel = false;
                while (token.getType() != Token.EOF) {
                    handled += token.getText();
                    pos = token.getCharPositionInLine();
                    if (token.getType() == MultiFarLexer.LABEL) {
                        tockenMap.addTocken(Esp2PortuTockenMap.LABEL_IN_FIXED_EXAMPLE_BODY);
                        String label = token.getText().replace("<i>{", "").replace("}</i>", "");
                        Phrase.Label lab = new Phrase.Label();
                        lab.setValue(label);
                        JAXBElement<Phrase.Label> partLabel = factory.createEntryHeadingVocablePartLabel(lab);
                        localNear.getNearChildren().add(partLabel);
                        afterLabel = true;
                        //} else if (token.getType() == MultiFarLexer.COMMA) {
                    } else if (token.getType() == MultiFarLexer.COMMA) {
                        tockenMap.addTocken(Esp2PortuTockenMap.COMMA_IN_FIXED_EXAMPLE_BODY);
                        localNear = factory.createNear();
                        localFar.getNear().add(localNear);
                    } else if (token.getType() == MultiFarLexer.SEMI
                            || token.getType() == MultiFarLexer.LONG_SLASH) {
                        tockenMap.addTocken(Esp2PortuTockenMap.SEMI_IN_FIXED_EXAMPLE_BODY);
                        localNear = factory.createNear();
                        localFar = factory.createTranslationFar();
                        localFar.getNear().add(localNear);
                        localtranslation.getFar().add(localFar);
                    } else {
                        String txt = token.getText();
                        if (token.getType() == MultiFarLexer.SHARP) {
                            txt = " ";
                        } else if (token.getType() == MultiFarLexer.DOUBLESHARP) {
                            txt = ", ";
                        } else if (token.getType() == MultiFarLexer.PLUS) {
                            txt = "+";
                        }
                        word += txt;
                    }
                    //System.out.print(token.getText());
                    token = localLexer.nextToken();
                    if (token.getType() == MultiFarLexer.SLASH) {
                        throw new ParseError(-1, "Слеш в теле пока не обрабатывается");
                    }

                    if (token.getType() == MultiFarLexer.SEMI
                            || token.getType() == MultiFarLexer.LONG_SLASH
                            || token.getType() == MultiFarLexer.COMMA
                            || token.getType() == MultiFarLexer.LABEL
                            || token.getType() == MultiFarLexer.EOF) {
                        Block transBlock = factory.createBlock();
                        if (!afterLabel) {
                            word = word.trim();
                        }
                        transBlock.setValue(word);
                        JAXBElement<Block> simpleTrans = factory.createEntryHeadingVocablePartSimple(transBlock);
                        localNear.getNearChildren().add(simpleTrans);
                        word = "";
                        afterLabel = false;
                    }
                }
            }
            //
            Phrase source = factory.createPhrase();
            Block srcBlock = factory.createBlock();
            srcBlock.setValue(header);
            JAXBElement<Block> simpleSrc = factory.createEntryHeadingVocablePartSimple(srcBlock);
            source.getPhraseChildren().add(simpleSrc);
            //
            example.getTranslation().add(localtranslation);
            example.setSource(source);
        } catch (Exception ex) {
            throw new ParseError(pos + basePos, ex.getMessage() + "; >> " + handled + "; pos " + pos + "; base pos " + basePos + "; src " + src);
        }
        return factory.createSubSenseFixedExample(example);
    }

    private void checkStartsWith(String header) {
        if (header.startsWith("1") || header.startsWith("2") || header.startsWith("3")
                || header.startsWith("4")
                || header.startsWith("5")
                || header.startsWith("6")
                || header.startsWith("7")
                || header.startsWith("8")
                || header.startsWith("9")) {
            throw new ErrorException("Фиксированный пример не должен начинаться с цифры");
        }
    }
}
